﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;
using System.Text.RegularExpressions;
using System.Data.SqlClient;

namespace Common
{
    public class Bootstrap
    {
        private static string ConfigFile { get; set; }
        private static Hashtable ConfigData
        {
            get { return Util.ConfigData; }
            set { Util.ConfigData = value; }
        }
        public SqlConnection Conn
        {
            get
            {
                if (Util.Conn == null)
                    Util.Conn = new SqlConnection();
                return Util.Conn;
            }
            set { Util.Conn = value; }
        }

        public Bootstrap()
        {
            Conn.Close();
            GetFromConfig();
            Conn.ConnectionString = ConfigData["ConnectionString"].ToString();
            Conn.Open();

        }

        private void GetFromConfig()
        {
            ConfigFile = App.Default["ConfigFile"].ToString();
            string Location = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
            if (!Location.Contains("tp-gestion-de-datos"))
                throw new FileLoadException("El archivo de configuración [\"" + ConfigFile + "\"] no está dentro de la carpeta de la aplicación \"tp-gestion-de-datos\"");
            do
            {
                Location = Location.Remove(Location.LastIndexOf('\\'));
            } while (Location.Remove(Location.LastIndexOf('\\')).Contains("tp-gestion-de-datos"));
            Location += "\\" + ConfigFile;
            ReadConfigFile(Location);

        }

        /// <summary>
        /// Lee y carga en el archivo de configuracion cada uno de los elementos que en el mismo encuentra.
        /// </summary>
        /// <param name="Location"></param>
        private void ReadConfigFile(string Location)
        {
            StreamReader file = StreamReader.Null;
            file = new StreamReader(Location);
            Util.ConfigData = new Hashtable();
            for (; !file.EndOfStream; )
            {
                string EvalThis = string.Empty;
                try
                {
                    EvalThis = file.ReadLine();
                }
                catch (Exception ex)
                {
                    throw new FileNotFoundException("No se encuentra el archivito de configuración", ConfigFile, ex);
                }

                //Regex R = new Regex("{[.*]}{\b?}={\b?}.*");
                string[] EvalThat = EvalThis.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);

                if (IsConfigElement(ref EvalThat))
                {
                    string Key = EvalThat[0].Trim();
                    string Value = EvalThat[1].Trim();

                    Key = GetElemKeyOrValue(Key);

                    ConfigData.Add((object)Key, (object)(GetElemKeyOrValue(Value).Replace("\n", string.Empty)));
                }
            }
            file.Close();
        }
        /// <summary>
        /// Despeja los corchetes y llaves para tomar limpios los valores.
        /// </summary>
        /// <param name="KeyOrValue"></param>
        /// <returns></returns>
        private static string GetElemKeyOrValue(string KeyOrValue)
        {
            KeyOrValue = KeyOrValue.Remove(KeyOrValue.Length - 1).Substring(1);
            return KeyOrValue;
        }

        /// <summary>
        /// Valida que tenga corchetes el Key y llaves el Value
        /// </summary>
        /// <param name="EvalThat"></param>
        /// <returns></returns>
        private static bool IsConfigElement(ref string[] EvalThat)
        {
            bool valueOk = false;
            bool cantOk = EvalThat.Length > 1;
            bool keyOk = false;
            if (cantOk)
            {
                keyOk = (EvalThat[0].Trim().StartsWith("[") &&
                     EvalThat[0].Trim().EndsWith("]"));
            }
            
            if (keyOk)
            {
                valueOk = (EvalThat[1].Trim().StartsWith("{") &&
                EvalThat[1].Trim().EndsWith("}"));
            }

            if (keyOk && !valueOk && EvalThat.Length > 2)
            {

                StringBuilder sb = new StringBuilder();
                for (int i = 1; i < EvalThat.Length; i++)
                {
                    sb.Append(EvalThat[i]);
                    if (EvalThat.Length - 1 != i)
                    {
                        sb.Append("=");
                    }
                }
                valueOk = sb.ToString().Trim().StartsWith("{") &&
                sb.ToString().Trim().EndsWith("}");
                if (valueOk)
                    EvalThat = new string[]{EvalThat[0],sb.ToString()};
            }
            return valueOk;
        }
    }
}
